#include "ptz_service.h"
#include "utils_log.h"
#include <sstream>

namespace El {
namespace Onvif {

PTZService::PTZService() {
    EL_INFO("PTZService initialized");
}

std::string PTZService::HandleRequest(const SoapMessage& request, const std::string& /*remoteAddr*/) {
    EL_DEBUG("PTZService handling request: " + request.action);
    
    if (request.action == "GetNodes") {
        return HandleGetNodes(request);
    } else if (request.action == "GetStatus") {
        return HandleGetStatus(request);
    } else if (request.action == "AbsoluteMove") {
        return HandleAbsoluteMove(request);
    } else if (request.action == "RelativeMove") {
        return HandleRelativeMove(request);
    } else if (request.action == "ContinuousMove") {
        return HandleContinuousMove(request);
    } else if (request.action == "Stop") {
        return HandleStop(request);
    } else if (request.action == "GetPresets") {
        return HandleGetPresets(request);
    } else if (request.action == "SetPreset") {
        return HandleSetPreset(request);
    } else if (request.action == "GotoPreset") {
        return HandleGotoPreset(request);
    }
    
    SoapMessageParser parser;
    return parser.GenerateSoapFault(SoapError::NotSupported, "PTZ action not supported: " + request.action);
}

std::string PTZService::HandleGetNodes(const SoapMessage& /*message*/) {
    std::ostringstream response;
    response << "    <tptz:GetNodesResponse>\n"
             << "      <tptz:PTZNode token=\"PTZ_Node_1\" FixedHomePosition=\"true\">\n"
             << "        <tt:Name>PTZ_Node_1</tt:Name>\n"
             << "        <tt:SupportedPTZSpaces>\n"
             << "          <tt:AbsolutePanTiltPositionSpace>\n"
             << "            <tt:URI>http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace</tt:URI>\n"
             << "            <tt:XRange>\n"
             << "              <tt:Min>-1.0</tt:Min>\n"
             << "              <tt:Max>1.0</tt:Max>\n"
             << "            </tt:XRange>\n"
             << "            <tt:YRange>\n"
             << "              <tt:Min>-1.0</tt:Min>\n"
             << "              <tt:Max>1.0</tt:Max>\n"
             << "            </tt:YRange>\n"
             << "          </tt:AbsolutePanTiltPositionSpace>\n"
             << "          <tt:AbsoluteZoomPositionSpace>\n"
             << "            <tt:URI>http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace</tt:URI>\n"
             << "            <tt:XRange>\n"
             << "              <tt:Min>0.0</tt:Min>\n"
             << "              <tt:Max>1.0</tt:Max>\n"
             << "            </tt:XRange>\n"
             << "          </tt:AbsoluteZoomPositionSpace>\n"
             << "        </tt:SupportedPTZSpaces>\n"
             << "        <tt:MaximumNumberOfPresets>255</tt:MaximumNumberOfPresets>\n"
             << "        <tt:HomeSupported>true</tt:HomeSupported>\n"
             << "        <tt:AuxiliaryCommands>Move</tt:AuxiliaryCommands>\n"
             << "      </tptz:PTZNode>\n"
             << "    </tptz:GetNodesResponse>\n";
    
    SoapMessageParser parser;
    return parser.GenerateSoapResponse(response.str(), "GetNodesResponse");
}

std::string PTZService::HandleGetStatus(const SoapMessage& /*message*/) {
    std::ostringstream response;
    response << "    <tptz:GetStatusResponse>\n"
             << "      <tptz:PTZStatus>\n"
             << "        <tt:Position>\n"
             << "          <tt:PanTilt x=\"0.0\" y=\"0.0\" space=\"http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace\"/>\n"
             << "          <tt:Zoom x=\"0.0\" space=\"http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace\"/>\n"
             << "        </tt:Position>\n"
             << "        <tt:MoveStatus>\n"
             << "          <tt:PanTilt>IDLE</tt:PanTilt>\n"
             << "          <tt:Zoom>IDLE</tt:Zoom>\n"
             << "        </tt:MoveStatus>\n"
             << "        <tt:UtcTime>2024-01-01T00:00:00Z</tt:UtcTime>\n"
             << "      </tptz:PTZStatus>\n"
             << "    </tptz:GetStatusResponse>\n";
    
    SoapMessageParser parser;
    return parser.GenerateSoapResponse(response.str(), "GetStatusResponse");
}

std::string PTZService::HandleAbsoluteMove(const SoapMessage& /*message*/) {
    std::ostringstream response;
    response << "    <tptz:AbsoluteMoveResponse/>\n";
    
    SoapMessageParser parser;
    return parser.GenerateSoapResponse(response.str(), "AbsoluteMoveResponse");
}

std::string PTZService::HandleRelativeMove(const SoapMessage& /*message*/) {
    std::ostringstream response;
    response << "    <tptz:RelativeMoveResponse/>\n";
    
    SoapMessageParser parser;
    return parser.GenerateSoapResponse(response.str(), "RelativeMoveResponse");
}

std::string PTZService::HandleContinuousMove(const SoapMessage& /*message*/) {
    std::ostringstream response;
    response << "    <tptz:ContinuousMoveResponse/>\n";
    
    SoapMessageParser parser;
    return parser.GenerateSoapResponse(response.str(), "ContinuousMoveResponse");
}

std::string PTZService::HandleStop(const SoapMessage& /*message*/) {
    std::ostringstream response;
    response << "    <tptz:StopResponse/>\n";
    
    SoapMessageParser parser;
    return parser.GenerateSoapResponse(response.str(), "StopResponse");
}

std::string PTZService::HandleGetPresets(const SoapMessage& /*message*/) {
    std::ostringstream response;
    response << "    <tptz:GetPresetsResponse>\n"
             << "      <tptz:Preset token=\"preset_home\" Name=\"Home\">\n"
             << "        <tt:PTZPosition>\n"
             << "          <tt:PanTilt x=\"0.0\" y=\"0.0\" space=\"http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace\"/>\n"
             << "          <tt:Zoom x=\"0.0\" space=\"http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace\"/>\n"
             << "        </tt:PTZPosition>\n"
             << "      </tptz:Preset>\n"
             << "    </tptz:GetPresetsResponse>\n";
    
    SoapMessageParser parser;
    return parser.GenerateSoapResponse(response.str(), "GetPresetsResponse");
}

std::string PTZService::HandleSetPreset(const SoapMessage& /*message*/) {
    std::ostringstream response;
    response << "    <tptz:SetPresetResponse>\n"
             << "      <tptz:PresetToken>preset_1</tptz:PresetToken>\n"
             << "    </tptz:SetPresetResponse>\n";
    
    SoapMessageParser parser;
    return parser.GenerateSoapResponse(response.str(), "SetPresetResponse");
}

std::string PTZService::HandleGotoPreset(const SoapMessage& /*message*/) {
    std::ostringstream response;
    response << "    <tptz:GotoPresetResponse/>\n";
    
    SoapMessageParser parser;
    return parser.GenerateSoapResponse(response.str(), "GotoPresetResponse");
}

std::string PTZService::EscapeXml(const std::string& input) const {
    std::string result = input;
    
    size_t pos = 0;
    while ((pos = result.find('&', pos)) != std::string::npos) {
        result.replace(pos, 1, "&amp;");
        pos += 5;
    }
    
    pos = 0;
    while ((pos = result.find('<', pos)) != std::string::npos) {
        result.replace(pos, 1, "&lt;");
        pos += 4;
    }
    
    pos = 0;
    while ((pos = result.find('>', pos)) != std::string::npos) {
        result.replace(pos, 1, "&gt;");
        pos += 4;
    }
    
    return result;
}

} // namespace Onvif
} // namespace El